package com.lyf.scm.plan.domain.service.impl;


import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageInfo;
import com.lyf.scm.common.enums.*;
import com.lyf.scm.common.model.ExcelExportDataDTO;
import com.lyf.scm.common.util.AdvancedSearchUtil;
import com.lyf.scm.common.util.ExcelExportUtil;
import com.lyf.scm.common.util.date.MyDateUtil;
import com.lyf.scm.common.util.style.GmvtargetCellWriterHandler;
import com.lyf.scm.plan.api.dto.GmvTargetDTO;
import com.lyf.scm.plan.api.dto.GmvTargetInfoDTO;
import com.lyf.scm.plan.domain.repository.GmvTargetRepository;
import com.lyf.scm.plan.domain.service.GmvTargetService;
import com.rome.arch.core.exception.RomeException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * description:
 * gmv指标serviceImpl
 *
 * @author: haodong
 * @data: 2020/7/8 16:34
 */
@Slf4j
@Service
public class GmvTargetServiceImpl implements GmvTargetService {

    @Resource
    private GmvTargetRepository gmvTargetRepository;


    /**
     * 按条件查询gmv指标
     *
     * @param gmvTarget
     * @return
     */
    @Override
    public PageInfo<GmvTargetInfoDTO> listBySelective(GmvTargetDTO gmvTarget) {
        //先查出满足分页数据
        PageInfo<GmvTargetDTO> pageInfo = gmvTargetRepository.listPageBySelective(gmvTarget);

        PageInfo<GmvTargetInfoDTO> resultPageInfo = new PageInfo<>();
        if (CollectionUtils.isNotEmpty(pageInfo.getList())) {
            // 获取分页后的参数
            this.getSearchConditions(pageInfo.getList(), gmvTarget);
            //根据满足分页后的参数查询数据
            List<GmvTargetDTO> resultList = gmvTargetRepository.listBySelective(gmvTarget);
            //设置分组依据的key值
            this.getGroupByKey(resultList);
            //将数据分组
            Map<String, List<GmvTargetDTO>> paramMap = resultList.stream().collect(Collectors.groupingBy(GmvTargetDTO::getGroupKey, Collectors.toList()));
            // 汇总指标数据
            List<GmvTargetInfoDTO> gmvTargetInfoList = this.getTargetList(paramMap, gmvTarget);

            resultPageInfo.setTotal(pageInfo.getTotal());
            resultPageInfo.setList(gmvTargetInfoList);
            return resultPageInfo;
        }
        return resultPageInfo;
    }


    /**
     * 查询全渠道gmv指标(范围)
     *
     * @param gmvTarget
     * @return
     */
    @Override
    public List<GmvTargetInfoDTO> listAllByCycles(GmvTargetDTO gmvTarget) {
        List<GmvTargetDTO> gmvTargetList = gmvTargetRepository.listAllByCycles(gmvTarget);
        if (CollectionUtils.isNotEmpty(gmvTargetList)) {
            //将数据分组
            Map<String, List<GmvTargetDTO>> paramMap = gmvTargetList.stream().collect(Collectors.groupingBy(GmvTargetDTO::getAllChannelCode, Collectors.toList()));
            // 汇总指标数据
            return this.getTargetList(paramMap, gmvTarget);
        }
        return this.getNullTargetList(gmvTarget);
    }

    /**
     * 批量新增
     *
     * @param gmvTargetList
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchSave(List<GmvTargetDTO> gmvTargetList) {
        //依据传递参数是否包含省份和公司分情况多条件批量查询
        List<GmvTargetDTO> filterList = gmvTargetList.stream().filter(item -> StringUtils.isNotEmpty(item.getProvinceCode())
                && StringUtils.isNotEmpty(item.getSalesOrganizationCode())).collect(Collectors.toList());
        List<GmvTargetDTO> gmvTargets = CollectionUtils.isNotEmpty(filterList) ?
                gmvTargetRepository.listByBatch(gmvTargetList,true) : gmvTargetRepository.listByBatch(gmvTargetList,false);

        Integer result = 0;
        // 如果查询有数据，说明有重复数据
        if (CollectionUtils.isNotEmpty(gmvTargets)){
            //取交集重新赋值后更新
            List<GmvTargetDTO> intersection = new ArrayList<>();
            gmvTargetList.forEach(gmv1 -> {
                intersection.addAll(
                        gmvTargets.stream().filter(gmv2 -> gmv2.getChannelCode().equals(gmv1.getChannelCode()) &&
                            gmv2.getSalesOrganizationCode().equals(gmv1.getSalesOrganizationCode()) &&
                            gmv2.getPriCategoryCode().equals(gmv1.getPriCategoryCode()) &&
                            gmv2.getPlanStartDate().compareTo(gmv1.getPlanStartDate()) == 0 &&
                            gmv2.getPlanEndDate().compareTo(gmv1.getPlanEndDate()) == 0)
                        .map(item -> {
                            item.setGmvOriginalTarget(gmv1.getGmvOriginalTarget());
                            item.setGmvTarget(gmv1.getGmvTarget());
                            item.setGmvRealTarget(gmv1.getGmvRealTarget());
                            item.setGrossProfitTarget(gmv1.getGrossProfitTarget());
                            item.setGrossProfitRealTarget(gmv1.getGrossProfitRealTarget());
                            item.setModifier(gmv1.getCreator());
                            item.setModifierName(gmv1.getChannelName());
                            return item;
                        }).collect(Collectors.toList()));
            });
            gmvTargetRepository.batchUpdate(intersection);
            //取差集新增
            List<GmvTargetDTO> subGmvTargetList = gmvTargetList.stream().filter(gmv1 ->
                    gmvTargets.stream().noneMatch(gmv2 -> gmv1.getChannelCode().equals(gmv2.getChannelCode()) &&
                            gmv1.getSalesOrganizationCode().equals(gmv2.getSalesOrganizationCode()) &&
                            gmv1.getPriCategoryCode().equals(gmv2.getPriCategoryCode()) &&
                            gmv2.getPlanStartDate().compareTo(gmv1.getPlanStartDate()) == 0 &&
                            gmv2.getPlanEndDate().compareTo(gmv1.getPlanEndDate()) == 0)).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(subGmvTargetList)){
                result = gmvTargetRepository.batchSave(subGmvTargetList);
                if (result != subGmvTargetList.size()) {
                    throw new RomeException(ResponseMsg.FAIL.getCode(), ResponseMsg.FAIL.getMsg());
                }
            }
        }else {
            result = gmvTargetRepository.batchSave(gmvTargetList);
            if (result != gmvTargetList.size()) {
                throw new RomeException(ResponseMsg.FAIL.getCode(), ResponseMsg.FAIL.getMsg());
            }
        }
        return Boolean.TRUE;
    }

    /**
     * excel导出
     *
     * @param gmvTargetDTO
     * @param type
     * @return void
     **/
    @Override
    public ExcelExportDataDTO exportExcel(GmvTargetDTO gmvTargetDTO, Integer type) throws Exception {
        //指标名称集合
        List<String> targets = GmvTargetEnum.getAllTargetsDesc();
        //获取日期标题
        List<String> dateTitles = MyDateUtil.processCyclesDate(gmvTargetDTO.getWeekDateList(), "MM.dd");
        List<GmvTargetDTO> gmvTargetList = new ArrayList<>();
        List<List<Object>> exportDataList = null;
        if (ExcelExportTypeEnum.SEARCHED_DATA_EXPORT.getType().equals(type)) {
            gmvTargetList = gmvTargetRepository.listAllByCycles(gmvTargetDTO);
        }
        //当前页数据导出
        if (ExcelExportTypeEnum.CURRENT_PAGE_EXPORT.getType().equals(type)) {
            PageInfo<GmvTargetDTO> pageInfo = gmvTargetRepository.listPageBySelective(gmvTargetDTO);
            if (CollectionUtils.isEmpty(pageInfo.getList())) {
                throw new RomeException(ResponseMsg.FAIL_2005.getCode(), ResponseMsg.FAIL_2005.getMsg());
            }
            //获取分页数据
            this.getSearchConditions(pageInfo.getList(), gmvTargetDTO);
            //根据满足分页后的参数查询数据
            gmvTargetList= gmvTargetRepository.listBySelective(gmvTargetDTO);
        }
        List<Integer> checkedIndex = null;
        //当前页勾选数据导出
        if (ExcelExportTypeEnum.CHECKED_BOX_EXPORT.getType().equals(type)) {
            PageInfo<GmvTargetDTO> pageInfo = gmvTargetRepository.listPageBySelective(gmvTargetDTO);
            if (CollectionUtils.isEmpty(pageInfo.getList())) {
                throw new RomeException(ResponseMsg.FAIL_2005.getCode(), ResponseMsg.FAIL_2005.getMsg());
            }
            //获取分页数据
            this.getSearchConditions(pageInfo.getList(), gmvTargetDTO);
            //根据满足分页后的参数查询数据
            gmvTargetList= gmvTargetRepository.listBySelective(gmvTargetDTO);
            //获取分页数据
            int start = (gmvTargetDTO.getPageNum() - 1) * gmvTargetDTO.getPageSize();
            checkedIndex = gmvTargetDTO.getRowIndex().stream().map(item -> item + start).collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(gmvTargetList)) {
            throw new RomeException(ResponseMsg.FAIL_2005.getCode(), ResponseMsg.FAIL_2005.getMsg());
        }
        //设置分组依据的key值
        this.getGroupByKey(gmvTargetList);
        //将数据分组
        Map<String, List<GmvTargetDTO>> paramMap = gmvTargetList.stream().collect(Collectors.groupingBy(GmvTargetDTO::getGroupKey, Collectors.toList()));
        List<GmvTargetInfoDTO> targetList = this.getTargetList(paramMap, gmvTargetDTO);
        //全部数据导出
        exportDataList = this.getExcelTargetList(targetList, gmvTargetDTO, targets, dateTitles, checkedIndex);
        //获取所有查询条件标识
        List<String> conditions = this.getConditions(gmvTargetDTO);
        //获取excel标题 同时返回高级搜索标题的数量
        List<List<String>> heads = new ArrayList<>();
        int mergeCellsColumns = this.setExcelTitles(heads, conditions, dateTitles);
        return ExcelExportUtil.getExcelExportData(mergeCellsColumns, exportDataList, heads, targets.size(), new GmvtargetCellWriterHandler());
    }

    /**
     * 更新销售额目标
     * @param gmvTarget
     * @return
     */
    @Override
    public Boolean updateTarget(List<GmvTargetDTO> gmvTarget) {
        List<GmvTargetDTO> updateTargetList = new ArrayList<>();
        //根据id集合查询
        List<Long> idList = new ArrayList<>();
        gmvTarget.forEach(item -> idList.addAll(item.getIdList()));
        List<GmvTargetDTO> gmvTargetList = gmvTargetRepository.listByIdList(idList);

        gmvTarget.forEach(gmv -> {
            BigDecimal sumTarget = gmvTargetList.stream().filter(item -> gmv.getIdList().contains(item.getId()))
                    .map(GmvTargetDTO::getGmvOriginalTarget).reduce(BigDecimal.ZERO, BigDecimal::add);
            updateTargetList.addAll(gmvTargetList.stream().filter(item -> gmv.getIdList().contains(item.getId()))
                    .map(val -> {
                        GmvTargetDTO target = new GmvTargetDTO();
                        BigDecimal resTarget = sumTarget.compareTo(BigDecimal.ZERO) == 0 ?
                                sumTarget : (val.getGmvOriginalTarget().divide(sumTarget, 10, BigDecimal.ROUND_HALF_UP)).multiply(gmv.getGmvTarget());
                        target.setId(val.getId());
                        target.setGmvTarget(resTarget.setScale(3,BigDecimal.ROUND_HALF_UP));
                        target.setModifier(gmv.getModifier());
                        target.setModifierName(gmv.getModifierName());
                        target.setVersionNo(val.getVersionNo());
                        return target;
                    }).collect(Collectors.toList()));

        });
        gmvTargetRepository.batchUpdate(updateTargetList);

        return Boolean.TRUE;
    }

    private int setExcelTitles(List<List<String>> heads, List<String> conditions, List<String> dateTitles) {
        //获取高级搜索标题
        this.getExcelAdvancedSearchTitle(heads, conditions);
        int result = heads.size();
        //加入指标标题
        List<String> targetTitle = new ArrayList<>();
        targetTitle.add(ExcelExportTitleEnum.TARGET_TITLE.getTitle());
        heads.add(targetTitle);
        //加入日期标题
        AdvancedSearchUtil.getExcelDateTitle(heads, dateTitles);
        return result;
    }

    /**
     * Excel表头
     *
     * @param heads
     * @param conditions
     */
    private void getExcelAdvancedSearchTitle(List<List<String>> heads, List<String> conditions) {
        setList(heads, ExcelExportTitleEnum.CHANNEL_TITLE.getTitle());
        if (conditions.contains(BaseSearchColumnEnum.PROVINCE_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.AREA_TITLE.getTitle());
        }
        if (conditions.contains(BaseSearchColumnEnum.PRI_CATEGORY_CODE.getColumn())) {
            setList(heads, ExcelExportTitleEnum.CATEGORY_TITLE.getTitle());
        }
        if (conditions.contains("salesOrganizationCode")) {
            setList(heads, ExcelExportTitleEnum.ORGANIZATION_TITLE.getTitle());
        }
    }

    /**
     * 获取标题行list
     *
     * @param heads
     * @param title
     */
    private static void setList(List<List<String>> heads, String title) {
        List<String> list = new ArrayList<>();
        list.add(title);
        heads.add(list);
    }

    /**
     * 获取分组条件
     *
     * @param gmvTargetDTO
     * @return
     */
    private List<String> getConditions(GmvTargetDTO gmvTargetDTO) {
        List<String> conditions = new ArrayList<>();
        if (!CollectionUtils.isEmpty(gmvTargetDTO.getChannelCodeList())) {
            conditions.add(BaseSearchColumnEnum.CHANNEL_CODE.getColumn());
        }
        if (!CollectionUtils.isEmpty(gmvTargetDTO.getProvinceCodeList())) {
            conditions.add(BaseSearchColumnEnum.PROVINCE_CODE.getColumn());
        }
        if (!CollectionUtils.isEmpty(gmvTargetDTO.getPriCategoryCodeList())) {
            conditions.add(BaseSearchColumnEnum.PRI_CATEGORY_CODE.getColumn());
        }
        if (!CollectionUtils.isEmpty(gmvTargetDTO.getSalesOrganizationList())) {
            conditions.add("salesOrganizationCode");
        }
        return conditions;
    }

    /**
     * Excel中的每条数据
     *
     * @param paramMap
     * @param gmvTarget
     * @param targets
     * @param dateTitles
     * @return
     */
    private List<List<Object>> getExcelTargetList(List<GmvTargetInfoDTO> paramMap, GmvTargetDTO gmvTarget, List<String> targets, List<String> dateTitles, List<Integer> checkedIndex) {
        List<Map<String, Date>> weekDateList = gmvTarget.getWeekDateList();
        //获取excel数据
        List<List<Object>> exportDataList = new ArrayList<>();
        //组下标
        AtomicInteger groupIndex = new AtomicInteger(0);
        paramMap.forEach(gmv -> {

            if (!CollectionUtils.isEmpty(checkedIndex)) {
                if (!checkedIndex.contains(groupIndex.get())) {
                    groupIndex.incrementAndGet();
                    return;
                }
            }
            for (int i = 0; i < targets.size(); i++) {
                List<Object> itemRow = new ArrayList<>();
                //加入渠道，区域，品类，商品  信息
                this.setExcelRowAdvancedSearchCondition(gmv, itemRow);
                //加入指标
                itemRow.add(targets.get(i));
                //加入数据
                for (int j = 0; j < dateTitles.size(); j++) {
                    //获取指标集合，这里没有排序，默认使用枚举的顺序
                    switch (i) {
                        case 0:
                            itemRow.add(gmv.getGmvTarget().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : gmv.getGmvTarget().get(j).setScale(7,BigDecimal.ROUND_HALF_UP));
                            break;
                        case 1:
                            itemRow.add(gmv.getGmvRealTarget().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : gmv.getGmvRealTarget().get(j).setScale(12,BigDecimal.ROUND_HALF_UP));
                            break;
                        case 2:
                            itemRow.add(gmv.getGmvTargetAcRate().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : gmv.getGmvTargetAcRate().get(j));
                            break;
                        case 3:
                            itemRow.add(gmv.getGmvTargetDifference().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : gmv.getGmvTargetDifference().get(j).setScale(6,BigDecimal.ROUND_HALF_UP));
                            break;
                        case 4:
                            itemRow.add(gmv.getGroProTarget().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : gmv.getGroProTarget().get(j).setScale(6,BigDecimal.ROUND_HALF_UP));
                            break;
                        case 5:
                            itemRow.add(gmv.getGroProRealTarget().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : gmv.getGroProRealTarget().get(j).setScale(6,BigDecimal.ROUND_HALF_UP));
                            break;
                        case 6:
                            itemRow.add(gmv.getGroProAcRate().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : gmv.getGroProAcRate().get(j));
                            break;
                        case 7:
                            itemRow.add(gmv.getGroProDifference().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : gmv.getGroProDifference().get(j).setScale(6,BigDecimal.ROUND_HALF_UP));
                            break;
                        default:
                            break;
                    }
                }
                exportDataList.add(itemRow);
            }
            groupIndex.incrementAndGet();
        });
        return exportDataList;
    }

    /**
     * excel每行数据设置 高级搜索  信息
     *
     * @param gmvTargetInfo
     * @param itemRow
     * @return void
     **/
    private void setExcelRowAdvancedSearchCondition(GmvTargetInfoDTO gmvTargetInfo, List<Object> itemRow) {
        if (!StringUtils.isEmpty(gmvTargetInfo.getChannel())) {
            itemRow.add(gmvTargetInfo.getChannel());
        } else {
            itemRow.add("全渠道");
        }
        if (!StringUtils.isEmpty(gmvTargetInfo.getArea())) {
            itemRow.add(gmvTargetInfo.getArea());
        }
        if (!StringUtils.isEmpty(gmvTargetInfo.getCategory())) {
            itemRow.add(gmvTargetInfo.getCategory());
        }
        if (!StringUtils.isEmpty(gmvTargetInfo.getSalesOrganization())) {
            itemRow.add(gmvTargetInfo.getSalesOrganization());
        }
    }

    /**
     * 查询数据为空时的处理
     * @param gmvTarget
     * @return
     */
    private List<GmvTargetInfoDTO> getNullTargetList(GmvTargetDTO gmvTarget) {
        List<Map<String, Date>> weekDateList = gmvTarget.getWeekDateList();
        List<GmvTargetInfoDTO> gmvTargetInfoList = new ArrayList<>();
        GmvTargetInfoDTO gmvTargetInfo = new GmvTargetInfoDTO();
        List<BigDecimal> getGmvTargetList = new ArrayList<>();
        List<BigDecimal> getGmvRealTargetList = new ArrayList<>();
        List<BigDecimal> getGrossProfitTargetList = new ArrayList<>();
        List<BigDecimal> getGrossProfitRealTargetList = new ArrayList<>();
        List<BigDecimal> gmvTargetDifferenceList = new ArrayList<>();
        List<BigDecimal> groProDifferenceList = new ArrayList<>();
        List<BigDecimal> gmvTargetAcRateList = new ArrayList<>();
        List<BigDecimal> groProAcRateList = new ArrayList<>();
        weekDateList.forEach(date -> {
            getGmvTargetList.add(BigDecimal.ZERO);
            getGmvRealTargetList.add(BigDecimal.ZERO);
            getGrossProfitTargetList.add(BigDecimal.ZERO);
            getGrossProfitRealTargetList.add(BigDecimal.ZERO);
            gmvTargetDifferenceList.add(BigDecimal.ZERO);
            groProDifferenceList.add(BigDecimal.ZERO);
            gmvTargetAcRateList.add(BigDecimal.ZERO);
            groProAcRateList.add(BigDecimal.ZERO);
        });
        gmvTargetInfo.setGmvTargetLabel(GmvTargetEnum.GMV_TARGET.getDesc());
        gmvTargetInfo.setGmvTarget(getGmvTargetList);
        gmvTargetInfo.setGmvRealTargetLabel(GmvTargetEnum.GMV_REAL_TARGET.getDesc());
        gmvTargetInfo.setGmvRealTarget(getGmvRealTargetList);
        gmvTargetInfo.setGroProTargetLabel(GmvTargetEnum.GRO_PRO_TARGET.getDesc());
        gmvTargetInfo.setGroProTarget(getGrossProfitTargetList);
        gmvTargetInfo.setGroProRealTargetLabel(GmvTargetEnum.GRO_PRO_REAL_TARGET.getDesc());
        gmvTargetInfo.setGroProRealTarget(getGrossProfitRealTargetList);
        gmvTargetInfo.setGmvTargetDifferenceLabel(GmvTargetEnum.GMV_TARGET_DIFFERENCE.getDesc());
        gmvTargetInfo.setGmvTargetDifference(gmvTargetDifferenceList);
        gmvTargetInfo.setGroProDifferenceLabel(GmvTargetEnum.GRO_PRO_DIFFERENCE.getDesc());
        gmvTargetInfo.setGroProDifference(groProDifferenceList);
        gmvTargetInfo.setGmvTargetAcRateLabel(GmvTargetEnum.GMV_TARGET_AC_RATE.getDesc());
        gmvTargetInfo.setGmvTargetAcRate(gmvTargetAcRateList);
        gmvTargetInfo.setGroProAcRateLabel(GmvTargetEnum.GRO_PRO_AC_RATE.getDesc());
        gmvTargetInfo.setGroProAcRate(groProAcRateList);
        gmvTargetInfoList.add(gmvTargetInfo);
        return gmvTargetInfoList;
    }

    /**
     * 汇总分组后的数据
     *
     * @param paramMap
     * @param gmvTarget
     * @return
     */
    private List<GmvTargetInfoDTO> getTargetList(Map<String, List<GmvTargetDTO>> paramMap, GmvTargetDTO gmvTarget) {
        List<GmvTargetInfoDTO> gmvTargetInfoList = new ArrayList<>();
        List<Map<String, Date>> weekDateList = gmvTarget.getWeekDateList();
        paramMap.keySet().forEach(key -> {
            GmvTargetInfoDTO gmvTargetInfo = new GmvTargetInfoDTO();
            // 设置目标GMV
            List<BigDecimal> getGmvTargetList = new ArrayList<>();
            weekDateList.forEach(date -> getGmvTargetList.add(paramMap.get(key).stream()
                    .filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 &&
                            item.getPlanEndDate().compareTo(date.get("endTime")) == 0)
                    .map(GmvTargetDTO::getGmvTarget).reduce(BigDecimal.ZERO, BigDecimal::add)));
            gmvTargetInfo.setGmvTargetLabel(GmvTargetEnum.GMV_TARGET.getDesc());
            gmvTargetInfo.setGmvTarget(getGmvTargetList);
            // 设置实际GMV
            List<BigDecimal> getGmvRealTargetList = new ArrayList<>();
            weekDateList.forEach(date -> getGmvRealTargetList.add(paramMap.get(key).stream()
                    .filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 &&
                            item.getPlanEndDate().compareTo(date.get("endTime")) == 0)
                    .map(GmvTargetDTO::getGmvRealTarget).reduce(BigDecimal.ZERO, BigDecimal::add)));
            gmvTargetInfo.setGmvRealTargetLabel(GmvTargetEnum.GMV_REAL_TARGET.getDesc());
            gmvTargetInfo.setGmvRealTarget(getGmvRealTargetList);
            // 设置目标毛利额
            List<BigDecimal> getGrossProfitTargetList = new ArrayList<>();
            weekDateList.forEach(date -> getGrossProfitTargetList.add(paramMap.get(key).stream()
                    .filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 &&
                            item.getPlanEndDate().compareTo(date.get("endTime")) == 0)
                    .map(GmvTargetDTO::getGrossProfitTarget).reduce(BigDecimal.ZERO, BigDecimal::add)));
            gmvTargetInfo.setGroProTargetLabel(GmvTargetEnum.GRO_PRO_TARGET.getDesc());
            gmvTargetInfo.setGroProTarget(getGrossProfitTargetList);
            // 设置实际毛利额
            List<BigDecimal> getGrossProfitRealTargetList = new ArrayList<>();
            weekDateList.forEach(date -> getGrossProfitRealTargetList.add(paramMap.get(key).stream()
                    .filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 &&
                            item.getPlanEndDate().compareTo(date.get("endTime")) == 0)
                    .map(GmvTargetDTO::getGrossProfitRealTarget).reduce(BigDecimal.ZERO, BigDecimal::add)));
            gmvTargetInfo.setGroProRealTargetLabel(GmvTargetEnum.GRO_PRO_REAL_TARGET.getDesc());
            gmvTargetInfo.setGroProRealTarget(getGrossProfitRealTargetList);
            // 设置GMV差值
            List<BigDecimal> gmvTargetDifferenceList = new ArrayList<>();
            weekDateList.forEach(date -> gmvTargetDifferenceList.add(paramMap.get(key).stream()
                    .filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 &&
                            item.getPlanEndDate().compareTo(date.get("endTime")) == 0)
                    .map(val -> val.getGmvRealTarget().subtract(val.getGmvTarget()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add)));
            gmvTargetInfo.setGmvTargetDifferenceLabel(GmvTargetEnum.GMV_TARGET_DIFFERENCE.getDesc());
            gmvTargetInfo.setGmvTargetDifference(gmvTargetDifferenceList);
            // 设置毛利额差值
            List<BigDecimal> groProDifferenceList = new ArrayList<>();
            weekDateList.forEach(date -> groProDifferenceList.add(paramMap.get(key).stream()
                    .filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 &&
                            item.getPlanEndDate().compareTo(date.get("endTime")) == 0)
                    .map(val -> val.getGrossProfitRealTarget().subtract(val.getGrossProfitTarget()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add)));
            gmvTargetInfo.setGroProDifferenceLabel(GmvTargetEnum.GRO_PRO_DIFFERENCE.getDesc());
            gmvTargetInfo.setGroProDifference(groProDifferenceList);
            // 设置GMV达成率:实际GMV/目标GMV  设置毛利额达成率:实际毛利额/目标毛利额
            List<BigDecimal> gmvTargetAcRateList = new ArrayList<>();
            List<BigDecimal> groProAcRateList = new ArrayList<>();
            for (int i = 0; i < weekDateList.size(); i++) {
                gmvTargetAcRateList.add((getGmvTargetList.get(i).compareTo(BigDecimal.ZERO) == 0 ?
                        BigDecimal.ZERO : getGmvRealTargetList.get(i).divide(getGmvTargetList.get(i), 7, BigDecimal.ROUND_HALF_UP)));
                groProAcRateList.add((getGrossProfitTargetList.get(i).compareTo(BigDecimal.ZERO) == 0 ?
                        BigDecimal.ZERO : getGrossProfitRealTargetList.get(i).divide(getGrossProfitTargetList.get(i), 7, BigDecimal.ROUND_HALF_UP)));
            }
            gmvTargetInfo.setGmvTargetAcRateLabel(GmvTargetEnum.GMV_TARGET_AC_RATE.getDesc());
            gmvTargetInfo.setGmvTargetAcRate(gmvTargetAcRateList);
            gmvTargetInfo.setGroProAcRateLabel(GmvTargetEnum.GRO_PRO_AC_RATE.getDesc());
            gmvTargetInfo.setGroProAcRate(groProAcRateList);
            //获取id
            List<List<Long>> idList = new ArrayList<>();
            weekDateList.forEach(date -> idList.add(paramMap.get(key).stream()
                    .filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 &&
                            item.getPlanEndDate().compareTo(date.get("endTime")) == 0)
                    .map(GmvTargetDTO::getId).collect(Collectors.toList())));
            gmvTargetInfo.setIdList(idList);
            //获取渠道、区域、商品信息
            this.getInfoData(paramMap.get(key), gmvTargetInfo);
            gmvTargetInfoList.add(gmvTargetInfo);
        });
        return gmvTargetInfoList;
    }

    /**
     * 设置分组依据的key值
     *
     * @param gmvTargetList
     * @return
     */
    private List<GmvTargetDTO> getGroupByKey(List<GmvTargetDTO> gmvTargetList) {

        gmvTargetList.forEach(item -> {
            StringBuilder keyStr = new StringBuilder();
            keyStr.append(ObjectUtil.isNotNull(item.getAllChannelCode()) ? item.getAllChannelCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getChannelCode()) ? item.getChannelCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getPriCategoryCode()) ? item.getPriCategoryCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getProvinceCode()) ? item.getProvinceCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getSalesOrganizationCode()) ? item.getSalesOrganizationCode() : "");
            item.setGroupKey(keyStr.toString());
        });
        return gmvTargetList;
    }

    /**
     * 获取渠道、区域、商品信息
     *
     * @param gmvTargetDTOList
     * @param gmvTargetInfo
     * @return
     */
    private GmvTargetInfoDTO getInfoData(List<GmvTargetDTO> gmvTargetDTOList, GmvTargetInfoDTO gmvTargetInfo) {

        // 区域信息
        gmvTargetInfo.setArea(gmvTargetDTOList.stream().filter(item -> ObjectUtil.isNotNull(item.getProvinceName())).map(GmvTargetDTO::getProvinceName).distinct().collect(Collectors.joining()));
        // 渠道信息
        gmvTargetInfo.setChannel(gmvTargetDTOList.stream().filter(item -> ObjectUtil.isNotNull(item.getChannelName())).map(GmvTargetDTO::getChannelName).distinct().collect(Collectors.joining()));
        // 品类信息
        gmvTargetInfo.setCategory(gmvTargetDTOList.stream().filter(item -> ObjectUtil.isNotNull(item.getPriCategoryName())).map(GmvTargetDTO::getPriCategoryName).distinct().collect(Collectors.joining()));
        //子公司信息
        gmvTargetInfo.setSalesOrganization(gmvTargetDTOList.stream().filter(item -> ObjectUtil.isNotNull(item.getSalesOrganizationName())).map(GmvTargetDTO::getSalesOrganizationName).distinct().collect(Collectors.joining()));
        return gmvTargetInfo;
    }

    /**
     * 获取分页后的参数
     * @param gmvTargetList
     * @param gmvTarget
     */
    private void getSearchConditions(List<GmvTargetDTO> gmvTargetList, GmvTargetDTO gmvTarget) {
        gmvTarget.setAllChannelCode(
                ObjectUtil.isNotNull(gmvTargetList.get(0).getAllChannelCode()) ? gmvTargetList.get(0).getAllChannelCode() : "");
        gmvTarget.setChannelCode(
                ObjectUtil.isNotNull(gmvTargetList.get(0).getChannelCode()) ? gmvTargetList.get(0).getChannelCode() : "");
        gmvTarget.setPriCategoryCode(
                ObjectUtil.isNotNull(gmvTargetList.get(0).getPriCategoryCode()) ? gmvTargetList.get(0).getPriCategoryCode() : "");
        gmvTarget.setProvinceCode(
                ObjectUtil.isNotNull(gmvTargetList.get(0).getProvinceCode()) ? gmvTargetList.get(0).getProvinceCode() : "");
        gmvTarget.setSalesOrganizationCode(
                ObjectUtil.isNotNull(gmvTargetList.get(0).getSalesOrganizationCode()) ? gmvTargetList.get(0).getSalesOrganizationCode() : "");
        gmvTarget.setGmvTargetList(gmvTargetList);
    }
    @Override
    public void delete(String opSign) {
        gmvTargetRepository.delete(opSign);
    }
}
